home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FM Towns: Free Software Collection 4
/
FM Towns Free Software Collection 4 - Disc 1.iso
/
t_os
/
tie
/
src
/
event.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-10-18
|
11KB
|
487 lines
/*
マウス イベント処理ライブラリ
1990.9.11 Make By ken
*/
#include <stdio.h>
#include <stdlib.h>
#include <egb.h>
#include <mos.h>
#include <msdos.cf>
#include <snd.h>
#include "tie.h"
#define MAX_EVENT 256
#define MAX_EVT 16
static int enable_cancel = TRUE ;
static int enable_ground = TRUE ;
static int evt_max = 0 ;
static int evt_free = ERR ;
static int last_node = ERR ;
static int max_cancel = 0 ;
static int max_ground = 0 ;
static EVENT evt_node[ MAX_EVENT ] ;
static EVT cancel[ MAX_EVT ] ;
static EVT ground[ MAX_EVT ] ;
extern int EVT_get_node( void ) ;
extern void EVT_free_node( int ) ;
extern int EVT_chk( EVENT *, int, int, int ) ;
extern EVT *EVT_chk_cancel( int, int ) ;
extern EVT *EVT_chk_ground( int, int ) ;
#define padU(x) ( ((x) & 0x01) == 0 ? TRUE : FALSE )
#define padD(x) ( ((x) & 0x02) == 0 ? TRUE : FALSE )
#define padL(x) ( ((x) & 0x04) == 0 ? TRUE : FALSE )
#define padR(x) ( ((x) & 0x08) == 0 ? TRUE : FALSE )
#define padA(x) ( ((x) & 0x10) == 0 ? TRUE : FALSE )
#define padB(x) ( ((x) & 0x20) == 0 ? TRUE : FALSE )
/* マウスとパッドを区別せず扱う位置情報取得ルーチン */
/* マウスとパッドを区別せず扱う位置情報取得ルーチン */
void MOS_PAD_rdpos( int *sw, int *x, int *y )
{
static int pad_num = 0 ;
static int count = 0 ;
auto int pad, dt, dx, dy ;
/* マウスカーソルの位置を読み込む */
MOS_rdpos( sw, x, y ) ;
/* パッドによる制御 */
SND_joy_in_1( 0, &pad ) ;
if( 0x3F != pad ) /* どれかON */
{
*sw = ( padB( pad ) ? 2 : 0 ) | ( padA( pad ) ? 1 : 0 ) ;
if( count ++ >= 10 )
{
count = 0 ;
if( ( dt = pad_num / 5 ) < 1 ) dt = 1 ;
if( dt > 16 ) dt = 16 ;
dx = dy = 0 ;
if( !padL( pad ) || !padR( pad ) )
dx = ( padL( pad ) ? (- dt) : ( padR( pad ) ? dt : 0 ) ) ;
if( !padU( pad ) || !padD( pad ) )
dy = ( padU( pad ) ? (- dt) : ( padD( pad ) ? dt : 0 ) ) ;
if( dx != 0 || dy != 0 )
MOS_setpos( *x += dx, *y += dy ) ;
pad_num ++ ;
}
}
else
pad_num = 0 ;
}
/* イベント待ちループ */
void EVT_loop( int min_level, int max_level )
{
REGS EVENT *ep ;
auto int i, sw, x, y ;
static int r_on = FALSE ;
MOS_PAD_rdpos( &sw, &x, &y ) ;
/* 右クリックによるキャンセル機能 */
if( enable_cancel != FALSE )
{
if( max_cancel > 0 )
{
if( r_on == TRUE && rbtn( sw ) == FALSE )
EVT_chk_cancel( min_level, max_level ) ;
r_on = rbtn( sw ) ;
}
sw &= 1 ;
}
if( last_node != ERR )
{
ep = &( evt_node[last_node] ) ;
if( ep->flg != FALSE &&
ep->level >= min_level && ep->level <= max_level &&
EVT_chk( ep, x, y, sw ) != EVT_NON )
return ;
}
last_node = ERR ;
for( i = 0 ; i < evt_max ; i++ )
{
ep = &( evt_node[i] ) ;
if( ep->flg != FALSE &&
ep->level >= min_level && ep->level <= max_level &&
EVT_chk( ep, x, y, sw ) != EVT_NON )
{
last_node = i ;
return ;
}
}
/* 余白のクリックによるイベント */
if( enable_ground != FALSE )
{
if( max_ground > 0 )
{
if( r_on == TRUE && rbtn( sw ) == FALSE )
EVT_chk_ground( min_level, max_level ) ;
r_on = rbtn( sw ) ;
}
}
}
int lbtn( int sw ) /* 左ボタンが押されていたら、TRUE */
{
return( ( sw & 1 ) != 0 ? TRUE : FALSE ) ;
}
int rbtn( int sw ) /* 右ボタンが押されていたら、TRUE */
{
return( ( sw & 2 ) != 0 ? TRUE : FALSE ) ;
}
void EVT_control_cancel( int flag )
{
enable_cancel = flag ;
}
void EVT_control_ground( int flag )
{
enable_ground = flag ;
}
static EVT *EVT_chk_cancel( int min, int max )
{
REGS int i ;
REGS EVT *cp ;
for( i = 0 ; i < max_cancel ; i ++ )
{
cp = &cancel[i] ;
if( cp->flg == TRUE && cp->level >= min && cp->level <= max )
{
(*cp->proc)() ;
return cp ;
}
}
return NULL ;
}
static EVT *EVT_chk_ground( int min, int max )
{
REGS int i ;
REGS EVT *cp ;
for( i = 0 ; i < max_ground ; i ++ )
{
cp = &ground[i] ;
if( cp->flg == TRUE && cp->level >= min && cp->level <= max )
{
(*cp->proc)() ;
return cp ;
}
}
return NULL ;
}
/* イベントの発生をチェック */
static int EVT_chk( REGS EVENT *ep, int x, int y, int sw )
{
auto int on ;
on = ( x >= ep->x1 && x <= ep->x2 &&
y >= ep->y1 && y <= ep->y2 ) ? TRUE : FALSE ;
switch( ep->now )
{
case EVT_OFF_MOS:
case EVT_MOVE_MOS:
case EVT_DLSEL_MOS:
case EVT_SELECT_MOS:
ep->now = EVT_NON ;
break ;
case EVT_NON:
if( on == TRUE )
{
ep->now = ( sw != 0 ? EVT_CLIP_MOS:EVT_ON_MOS ) ;
(*ep->proc)( ep, x, y, sw ) ;
}
break ;
case EVT_ON_MOS:
if( on == TRUE )
{
ep->now = ( sw != 0 ? EVT_CLIP_MOS : EVT_ON_MOS ) ;
(*ep->proc)( ep, x, y, sw ) ;
}
else
{
ep->now = EVT_OFF_MOS ;
(*ep->proc)( ep, x, y, sw ) ;
}
break ;
case EVT_CLIP_MOS:
if( on == TRUE )
{
if( sw == 0 ) /* ボタンを離した */
{
ep->now = EVT_SELECT_MOS ;
(*ep->proc)( ep, x, y, sw ) ;
}
}
else
{
ep->now = ( sw != 0 ? EVT_DOLACK_MOS : EVT_MOVE_MOS ) ;
(*ep->proc)( ep, x, y, sw ) ;
}
break ;
case EVT_DOLACK_MOS:
if( sw == 0 ) /* ボタンを離した */
{
ep->now = EVT_DLSEL_MOS ;
(*ep->proc)( ep, x, y, sw ) ;
}
else
{
ep->now = EVT_DOLACK_MOS ;
(*ep->proc)( ep, x, y, sw ) ;
}
break ;
case EVT_REP_MOS:
if( on == TRUE )
{
if( sw == 0 ) /* ボタンを離した */
{
ep->now = EVT_SELECT_MOS ;
(*ep->proc)( ep, x, y, sw ) ;
}
else
(*ep->proc)( ep, x, y, sw ) ;
}
else
{
ep->now = ( sw == 0 ? EVT_DOLACK_MOS : EVT_MOVE_MOS ) ;
(*ep->proc)( ep, x, y, sw ) ;
}
break ;
}
return ep->now ;
}
static int EVT_get_node( void )
{
auto int no ;
if( ( no = evt_free ) != ERR )
evt_free = evt_node[ evt_free ].level ;
else if( evt_max >= MAX_EVENT )
return ERR ;
else
no = evt_max ++ ;
return no ;
}
static void EVT_free_node( int no )
{
evt_node[ no ].flg = FALSE ;
evt_node[ no ].level = evt_free ;
evt_free = no ;
if( no == last_node )
last_node = ERR ;
}
void EVT_level_free( int level )
{
auto int i ;
REGS EVENT *ep ;
REGS EVT *cp ;
for( i = 0 ; i < MAX_EVENT ; i ++ )
{
ep = &( evt_node[ i ] ) ;
if( ep->flg != FALSE && ep->level == level )
EVT_free_node( i ) ;
}
for( i = 0 ; i < MAX_EVT ; i ++ )
{
cp = &( cancel[ i ] ) ;
if( cp->flg != FALSE && cp->level == level )
cp->flg = FALSE ;
cp = &( ground[ i ] ) ;
if( cp->flg != FALSE && cp->level == level )
cp->flg = FALSE ;
}
}
EVENT *EVT_set_node( int x1, int y1, int x2, int y2,
int level, void (*proc)(), int no, int rep )
{
auto int node ;
REGS EVENT *ep ;
if( ( node = EVT_get_node() ) == ERR )
return NULL ;
ep = &( evt_node[ node ] ) ;
ep->flg = TRUE ;
ep->level = level ;
ep->now = 0 ;
ep->no = no ;
ep->x1 = x1 ;
ep->y1 = y1 ;
ep->x2 = x2 ;
ep->y2 = y2 ;
ep->rep = rep ;
ep->proc = proc ;
return ep ;
}
EVT *EVT_set_cancel( int level, void (*proc)() )
{
REGS int i ;
auto EVT *cp ;
if( max_cancel < MAX_EVT )
cp = &cancel[ max_cancel ++ ] ;
else
{
for( i = 0 ; i < MAX_EVT ; i ++ )
if( cancel[i].flg == FALSE )
{
cp = &cancel[ i ] ;
break ;
}
if( i == MAX_EVT )
return( NULL ) ;
}
cp->flg = TRUE ;
cp->level = level ;
cp->proc = proc ;
return cp ;
}
void EVT_unset_cancel( int level )
{
REGS int i ;
REGS EVT *cp ;
for( i = 0 ; i < MAX_EVT ; i ++ )
{
cp = &( cancel[ i ] ) ;
if( cp->flg != FALSE && cp->level == level )
cp->flg = FALSE ;
}
}
EVT *EVT_set_ground( int level, void (*proc)() )
{
REGS int i ;
auto EVT *cp ;
if( max_ground < MAX_EVT )
cp = &ground[ max_ground ++ ] ;
else
{
for( i = 0 ; i < MAX_EVT ; i ++ )
if( ground[i].flg == FALSE )
{
cp = &ground[ i ] ;
break ;
}
if( i == MAX_EVT )
return( NULL ) ;
}
cp->flg = TRUE ;
cp->level = level ;
cp->proc = proc ;
return cp ;
}
void EVT_unset_ground( int level )
{
REGS int i ;
REGS EVT *cp ;
for( i = 0 ; i < MAX_EVT ; i ++ )
{
cp = &( ground[ i ] ) ;
if( cp->flg != FALSE && cp->level == level )
cp->flg = FALSE ;
}
}
void EVT_reset( void )
{
int i ;
evt_max = 0 ;
evt_free = ERR ;
last_node = ERR ;
max_cancel = 0 ;
for( i = 0 ; i < MAX_EVENT ; i ++ )
{
evt_node[ i ].flg = FALSE ;
evt_node[ i ].level = 0 ;
}
for( i = 0 ; i < MAX_EVT ; i ++ )
{
cancel[ i ].flg = ground[ i ].flg = FALSE ;
cancel[ i ].level = ground[ i ].level = 0 ;
}
}
/*
#define XPOS 64
#define YPOS 50
#define XNUM 32
#define YNUM ((MAX_EVENT/XNUM)+3)
#define XP 16
#define YP 20
void EVT_print_list( void )
{
int i ;
char tmp[128] ;
dsp_box( XPOS-8,YPOS, XPOS+XNUM*XP, YPOS+YP*YNUM, 5,5,5 ) ;
dsp_box( XPOS-6,YPOS+2, XPOS+XNUM*XP-2, YPOS+YP*YNUM-2, 7,8,5 ) ;
sprintf( tmp, "MAX_EVENT:%d evt_max:%3d evt_free:%3d",
MAX_EVENT, evt_max, evt_free ) ;
wrt( tmp, writepage, XPOS+32,YPOS+8, COL_15,COL_5, 16 ) ;
for( i = 0 ; i < MAX_EVENT ; i++ )
wrt( evt_node[i].flg ? "*" : ".", writepage,
XPOS+(i%XNUM)*XP,YPOS+YP*2+(i/XNUM)*YP, COL_15,COL_5, 16 ) ;
}
*/